﻿using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

/// <summary>
/// 外观模式：管理各个子系统，提供一个统一的上层接口
/// 中介者模式：负责各个子系统之间的通信
/// </summary>
public class GameFacade
{
    // 单例模式 -- 只允许存在一个实例
    private static GameFacade _instance = new GameFacade();
    public static GameFacade Insance { get { return _instance; } }
    private GameFacade() { }
    
    // 判断游戏是否结束
    private bool mIsGameOver = false;
    public bool isGameOver { get { return mIsGameOver; } }
    
    // 游戏中的各个系统
    private ArchievementSystem mArchievementSystem;
    private CampSystem mCampSystem;
    private CharacterSystem mCharacterSystem;
    private EnergySystem mEnergySystem;
    private GameEventSystem mGameEventSystem;
    private StageSystem mStageSystem;
    
    // 游戏中的UI系统
    private CampInfoUI mCampInfoUI;
    private GamePauseUI mGamePauseUI;
    private GameStateInfoUI mGameStateInfoUI;
    private SoldierInfoUI mSoldierInfoUI;
    
    // 初始化各个系统
    public void Init()
    {
        mArchievementSystem = new ArchievementSystem();
        mCampSystem = new CampSystem();
        mCharacterSystem = new CharacterSystem();
        mEnergySystem = new EnergySystem();
        mGameEventSystem = new GameEventSystem();
        mStageSystem = new StageSystem();

        mCampInfoUI = new CampInfoUI();
        mGamePauseUI = new GamePauseUI();
        mGameStateInfoUI = new GameStateInfoUI();
        mSoldierInfoUI = new SoldierInfoUI();

        mArchievementSystem.Init();
        mCampSystem.Init();
        mCharacterSystem.Init();
        mEnergySystem.Init();
        mGameEventSystem.Init();
        mStageSystem.Init();

        mCampInfoUI.Init();
        mGamePauseUI.Init();
        mGameStateInfoUI.Init();
        mSoldierInfoUI.Init();
        
        // 备忘录模式 -- 加载备忘录
        LoadMemento();
    }
    
    // 游戏更新时调用
    public void Update()
    {
        // 各个子系统更新
        mArchievementSystem.Update();
        mCampSystem.Update();
        mCharacterSystem.Update();
        mEnergySystem.Update();
        mGameEventSystem.Update();
        mStageSystem.Update();
        
        // 各个UI更新
        mCampInfoUI.Update();
        mGamePauseUI.Update();
        mGameStateInfoUI.Update();
        mSoldierInfoUI.Update();
    }
    
    // 游戏结束时释放资源
    public void Release()
    {
        mArchievementSystem.Release();
        mCampSystem.Release();
        mCharacterSystem.Release();
        mEnergySystem.Release();
        mGameEventSystem.Release();
        mStageSystem.Release();

        mCampInfoUI.Release();
        mGamePauseUI.Release();
        mGameStateInfoUI.Release();
        mSoldierInfoUI.Release();

        CreateMemento();
    }

    public Vector3 GetEnemyTargetPosition()
    {
        return mStageSystem.targetPosition;
    }

    public void ShowCampInfo(ICamp camp) {
        mCampInfoUI.ShowCampInfo(camp);
    }


    public void AddSoldier(ISoldier soldier)
    {
        mCharacterSystem.AddSoldier(soldier);
    }
    
    public void AddEnemy(IEnemy enemy)
    {
        mCharacterSystem.AddEnemy(enemy);
    }

    public void RemoveEnemy(IEnemy enemy)
    {
        mCharacterSystem.RemoveEnemey(enemy);
    }

    public bool TakeEnergy(int value)
    {
        return mEnergySystem.TakeEnergy(value);
    }

    public void RecycleEnergy(int value)
    {
        mEnergySystem.RecycleEnergy(value);
    }

    public void ShowMsg(string msg)
    {
        mGameStateInfoUI.ShowMsg(msg);
    }

    public void UpdateEnergySlider(int nowEnergy, int maxEnergy)
    {
        mGameStateInfoUI.UpdateEnergySlider(nowEnergy, maxEnergy);
    }

    /// <summary>
    /// 注册观察者
    /// </summary>
    /// <param name="eventType">事件类型</param>
    /// <param name="observer">观察者</param>
    public void RegisterObserver(GameEventType eventType, IGameEventObserver observer)
    {
        mGameEventSystem.RegisterObserver(eventType,observer);
    }

    public void RemoveObserver(GameEventType eventType, IGameEventObserver observer){
        mGameEventSystem.RemoveObserver(eventType,observer);
    }

    public void NotifySubject(GameEventType eventType)
    {
        mGameEventSystem.NotifySubject(eventType);
    }

    private void LoadMemento()
    {
        AchievementMemento memento = new AchievementMemento();
        memento.LoadData();
        mArchievementSystem.SetMemento(memento);
    }

    private void CreateMemento()
    {
        AchievementMemento memento= mArchievementSystem.CreateMemento();
        memento.SaveData();
    }

    public void RunVisitor(ICharacterVisitor visitor)
    {
        mCharacterSystem.RunVisitor(visitor);
    }
}

